

#include <utils/boundingboxbuilder.h>

ceBoundingBoxBuilder::ceBoundingBoxBuilder ()
	: _vb (0)
	, _data (0)
	, _stride (0)
{
}

ceBoundingBoxBuilder::~ceBoundingBoxBuilder ()
{
	if (_vb)
		{
			_vb->Unlock ();
			_vb = 0;
		}
}

bool ceBoundingBoxBuilder::Initialize (iVertexBuffer* vb, iVertexDeclaration* vd)
{
  static ceProgramParameterName positionName (PPB_Position0);
  const ceVertexElement* element = vd->GetElement (positionName, 0);
  if (!vb->Lock (element->Offset, (void**)(&_data), BAM_Read))
		{
			return false;
		}

	_vb = vb;
	_stride = element->Stride;
	return true;
}

void ceBoundingBoxBuilder::Close ()
{
	if (_vb)
		{
			_vb->Unlock ();
			_vb = 0;
		}
	_data = 0;
}


ceBoundingBox ceBoundingBoxBuilder::CreateBoundingBox (unsigned numVertices)
{
	ceBoundingBox bbox;
	bbox.Clear();

	for (unsigned i=0; i<numVertices; i++)
		{
			ceVector3f* v = reinterpret_cast<ceVector3f*>(&_data[i * _stride]);
			bbox.Add (*v);
		}
	bbox.Update ();
	return bbox;
}

ceBoundingBox ceBoundingBoxBuilder::CreateBoundingBox (unsigned numIndices, unsigned short* indices)
{
	ceBoundingBox bbox;
	bbox.Clear();

	for (unsigned i=0; i<numIndices; i++)
		{
			unsigned short idx = indices[i];
			ceVector3f* v = reinterpret_cast<ceVector3f*>(&_data[idx * _stride]);
			bbox.Add (*v);
		}
	bbox.Update ();

	return bbox;
}

ceBoundingBox ceBoundingBoxBuilder::CreateBoundingBox (unsigned numIndices, unsigned* indices)
{
	ceBoundingBox bbox;
	bbox.Clear();

	for (unsigned i=0; i<numIndices; i++)
		{
			unsigned idx = indices[i];
			ceVector3f* v = reinterpret_cast<ceVector3f*>(&_data[idx * _stride]);
			bbox.Add (*v);
		}
	bbox.Update ();

	return bbox;
}


ceBoundingBox ceBoundingBoxBuilder::CreateBoundingBox (unsigned offset, unsigned stride, unsigned numP, unsigned numQ)
{
	ceBoundingBox bbox;
	bbox.Clear();

	for (unsigned q=0; q<numQ; q++)
		{
			for (unsigned p=0; p<numP; p++)
				{
					unsigned idx = offset + q * stride + p;
					ceVector3f* v = reinterpret_cast<ceVector3f*>(&_data[idx * _stride]);
					bbox.Add (*v);
				}
		}
	bbox.Update ();

	return bbox;
}
